package com.achievement.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.unit.DataUnit;
import com.achievement.domain.dto.honor.*;
import com.achievement.domain.entity.ExpertReviewEntity;
import com.achievement.domain.entity.ReviewResultEntity;
import com.achievement.domain.param.honor.ExpertReviewParam;
import com.achievement.domain.vo.honor.ExpertGroupVO;
import com.achievement.domain.vo.honor.ExpertReviewVO;
import com.achievement.domain.vo.honor.AchievementExpertVO;
import com.achievement.mapper.ExpertReviewMapper;
import com.achievement.mapper.HonorApplyBookMapper;
import com.achievement.mapper.ReviewResultMapper;
import com.achievement.mappings.ExpertReviewMapping;
import com.achievement.mappings.ReviewResultMapping;
import com.achievement.service.IExpertReviewService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.utils.DateUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import org.springframework.transaction.annotation.Transactional;
@Service
public class ExpertReviewServiceImpl extends ServiceImpl<ExpertReviewMapper, ExpertReviewEntity> implements IExpertReviewService {
    @Autowired
    private ExpertReviewMapping mapping;
    @Autowired
    private ExpertReviewMapper mapper;
    @Autowired
    private HonorApplyBookMapper bookMapper;
    @Autowired
    private ReviewResultMapper reviewResultMapper;
    @Autowired
    private ReviewResultMapping reviewResultMapping;
    @Override
    public List<ExpertReviewVO> selectByPage(ExpertReviewParam param) {
        LambdaQueryWrapper<ExpertReviewEntity> queryWrapper = new LambdaQueryWrapper();
        List<ExpertReviewEntity> list=new ArrayList<>();
        queryWrapper.like(StringUtils.isNotEmpty(param.getReviewObjectName()), ExpertReviewEntity::getReviewObjectName, param.getReviewObjectName());
        queryWrapper.eq(StringUtils.isNotEmpty(param.getReviewSchemeId()), ExpertReviewEntity::getReviewSchemeId, param.getReviewSchemeId());
        queryWrapper.eq(StringUtils.isNotEmpty(param.getReviewObjectId()), ExpertReviewEntity::getReviewObjectId, param.getReviewObjectId());
        queryWrapper.eq(StringUtils.isNotEmpty(param.getBusinessType()), ExpertReviewEntity::getBusinessType, param.getBusinessType());
        queryWrapper.eq(StringUtils.isNotEmpty(param.getReviewStatus()), ExpertReviewEntity::getReviewStatus, param.getReviewStatus());
        queryWrapper.eq(StringUtils.isNotEmpty(param.getReviewPlanId()), ExpertReviewEntity::getReviewPlanId, param.getReviewPlanId());
        queryWrapper.eq(StringUtils.isNotEmpty(param.getReviewerId()), ExpertReviewEntity::getReviewerId, param.getReviewerId());
        queryWrapper.like(StringUtils.isNotEmpty(param.getReviewerName()), ExpertReviewEntity::getReviewerName, param.getReviewerName());
        list = this.list(queryWrapper);
        List<ExpertReviewVO> voList = list.stream().map(mapping::entity2Vo).collect(Collectors.toList());
        return voList;
    }
    @Override
    public List<ExpertReviewEntity> getListByConditions(ExpertReviewDTO patentDTO) {
        QueryWrapper<ExpertReviewEntity> queryWrapper = new QueryWrapper();
        List<ExpertReviewEntity> list = this.list(queryWrapper);
        return list;
    }

    @Override
    public ExpertReviewVO getInfoById(String id) {
        ExpertReviewEntity entity = this.getById(id);
        ExpertReviewVO ExpertReviewVO=mapping.entity2Vo(entity);
        return ExpertReviewVO;
    }

    @Override
    public boolean add(ExpertReviewDTO dto) {
        ExpertReviewEntity entity = mapping.dto2Entity(dto);
        return this.save(entity);
    }


    @Override
    public boolean update(ExpertReviewDTO dto) {
        ExpertReviewEntity entity = mapping.dto2Entity(dto);
        return this.updateById(entity);
    }

    @Override
    public boolean batchRemove(List<String> ids) {
        boolean returnResult=false;
        returnResult=this.removeByIds(ids);
        return returnResult;
    }

    @Override
    public boolean addOrUpdateExpertReview(HonorApplyBookExpertReviewDTO dto){
        boolean returnResult=true;
        LambdaQueryWrapper<ExpertReviewEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(StringUtils.isNotEmpty(dto.getHonorApplyBookId()), ExpertReviewEntity::getReviewObjectId, dto.getHonorApplyBookId());
        List<ExpertReviewEntity> list=this.list(queryWrapper);
        List<ExpertDTO> expertDTOS=dto.getExpertDTOS();
        if(CollUtil.isNotEmpty(expertDTOS)){//存在

                for(int i=0;i<list.size();i++){
                    String reviewerId=list.get(i).getReviewerId();
                    if(!expertDTOS.stream().anyMatch(expert -> expert.getId().equals(reviewerId))){//不存在
                        //删除系统内的 reviewer
                        LambdaQueryWrapper<ExpertReviewEntity> removeWrapper = new LambdaQueryWrapper();
                        removeWrapper.eq(ExpertReviewEntity::getReviewerId, reviewerId);
                        this.remove(removeWrapper);
                    }
                }
                for(int j=0;j<expertDTOS.size();j++){
                    String reviewerId=expertDTOS.get(j).getId();
                    if(!list.stream().anyMatch(expert -> expert.getReviewerId().equals(reviewerId))){//不存在
                        //插入
                        ExpertReviewEntity expertReviewEntity=new ExpertReviewEntity();
                        expertReviewEntity.setId(UUID.randomUUID().toString().replace("-",""));
                        expertReviewEntity.setReviewerId(reviewerId);
                        expertReviewEntity.setReviewObjectId(dto.getHonorApplyBookId());
                        expertReviewEntity.setReviewObjectName(dto.getHonorName());
                        expertReviewEntity.setReviewSchemeId(dto.getReviewSchemeId());
                        expertReviewEntity.setReviewerName(expertDTOS.get(j).getName());
                        expertReviewEntity.setReviewerId(expertDTOS.get(j).getId());
                        expertReviewEntity.setBusinessType("honorApply");
                        expertReviewEntity.setReviewStatus("notReview");
                        expertReviewEntity.setReviewPlanId(dto.getReviewPlanId());
                        this.save(expertReviewEntity);
                    }
                }

        }else{//不存 删除所有
            if(CollUtil.isNotEmpty(list)){
                List<String> ids = list.stream().map(a -> a.getId()).collect(Collectors.toList());
                returnResult=this.removeByIds(ids);
            }else{
                returnResult=true;
            }
        }
        return returnResult;
    }
    @Override
    public  List<ExpertReviewVO> selectByLambdaQueryWrapper(LambdaQueryWrapper<ExpertReviewEntity> expertReviewQueryWrapper){
        List<ExpertReviewEntity> expertReviewList=mapper.selectList(expertReviewQueryWrapper);
        List<ExpertReviewVO> expertReviewVoList = expertReviewList.stream().map(mapping::entity2Vo).collect(Collectors.toList());
        return expertReviewVoList;
    }
    @Override
    public List<ExpertGroupVO> expertGroupList(){
        return mapper.expertGroupList();
    }
    @Override
    public List<AchievementExpertVO> expertListByGroup(String id){
        return mapper.expertListByGroup(id);
    }

    @Transactional // 开启事务
    @Override
    public boolean reviewByExpert(ExpertReviewResultDTO dto,String expertId){
        String reviewerId=getReviewerIdByExpertId(expertId);
        if(!StringUtils.isNotBlank(reviewerId)){
            return false;
        }
        UpdateWrapper<ExpertReviewEntity> updateWrapper = new UpdateWrapper<>();
        Double remarkAll=0.0;
        if(ObjectUtils.isNotEmpty(dto.getReviewResultDTOs())){
            //先删除本地评审成绩
            LambdaQueryWrapper<ReviewResultEntity> removeWrapper = new LambdaQueryWrapper();
            removeWrapper.eq(ReviewResultEntity::getExpertReviewId, dto.getExpertReviewId());
            reviewResultMapper.delete(removeWrapper);

            //遍历插入评审分数
            for (ReviewResultDTO rd:dto.getReviewResultDTOs()){
                remarkAll+=rd.getReviewMark();
                ReviewResultEntity entity=reviewResultMapping.dto2Entity(rd);
                entity.setExpertReviewId(dto.getExpertReviewId());
                reviewResultMapper.insert(entity);
            }
        }
        // 设置更新条件
        updateWrapper.eq("reviewer_Id", reviewerId);
        updateWrapper.eq("review_Object_Id", dto.getReviewObjectId());

        // 设置更新字段
        updateWrapper.set("review_Status", dto.getReviewStatus());
        updateWrapper.set("review_Date", DateUtils.dateTimeNow());
        updateWrapper.set("review_Info", dto.getReviewInfo());
        updateWrapper.set("review_Result", dto.getReviewResult());
        updateWrapper.set("review_Mark", remarkAll);
        return this.update(null,updateWrapper);
    }

    /**
     * 判断分数不能为负数
     * @return
     */
    @Override
    public boolean checkMark(List<ReviewResultDTO>  reviewResultDTOs){
        boolean checkResult=true;
        if(!ObjectUtils.isEmpty(reviewResultDTOs)){
            //遍历插入评审分数
            for (ReviewResultDTO rd:reviewResultDTOs){
                if(ObjectUtils.isEmpty(rd.getReviewMark())||rd.getReviewMark()<0){
                    checkResult= false;
                    break;
                }
            }
        }
        return checkResult;
    }

    @Override
    public boolean reviewNoSubmitByExpert(String reviewObjectIds,String expertId){
        List<String> reviewObjectIdList= Arrays.asList(reviewObjectIds.split(","));
        UpdateWrapper<ExpertReviewEntity> updateWrapper = new UpdateWrapper<>();
        // 设置更新条件
        //expertId 需要去检索 biz_expert表的SYS_USER_ID和PERSON_ID共同检索reviewer_Id
        String reviewerId=getReviewerIdByExpertId(expertId);
        if(!StringUtils.isNotBlank(reviewerId)){
            return false;
        }
        updateWrapper.eq("reviewer_Id", reviewerId);
        updateWrapper.eq("business_type", "honorApply");
        updateWrapper.in("review_Object_Id", reviewObjectIdList);
        updateWrapper.set("review_Status", "submit");
        return this.update(null,updateWrapper);
    }
    /**
     * 成果评审-专家拒绝评审
     * @param dto 评审信息
     * @param expertId refuseReview
     */
    @Override
    public boolean refuseReviewByExpert(ExpertReviewDTO dto, String expertId){
        UpdateWrapper<ExpertReviewEntity> updateWrapper = new UpdateWrapper<>();
        String reviewerId=getReviewerIdByExpertId(expertId);
        if(!StringUtils.isNotBlank(reviewerId)){
            return false;
        }
        // 设置更新条件
        updateWrapper.eq("reviewer_Id", reviewerId);
        updateWrapper.eq("review_Object_Id", dto.getReviewObjectId());

        // 设置更新字段
        updateWrapper.set("review_Status", "refuseReview");
        updateWrapper.set("review_Info", dto.getReviewInfo());
        return this.update(null,updateWrapper);
    }
    @Override
    public String getReviewerIdByExpertId(String expertId) {
        AchievementExpertVO expertVO = bookMapper.ExpertById(expertId);
        if (expertVO != null && StringUtils.isNotBlank(expertVO.getId())) {
            return expertVO.getId();
        }
        return "";
    }
}
